"! Info:
The Array is a basic integer-indexed collection of objects. Smalltalk arrays are 1-based so the indices of an array will be [1..size]. Basic functionality is provided to perform insert, delete, and search operations on arrays.

Arrays may be created either with one of the \"new\" or \"with:\" methods, or with the array literal syntax \"#( .... )\"
Examples:
|a b c|

\"Create a new array with 100 elements\"
a := Array new: 100.
\"Create a new array with 1 element: 42\"
b := Array with: 42.
\"Create a new array with elements 1,2,4,8,16\"
c := #(1 2 4 8 16).
"
Collection subclass: Array [
<category: 'Library-Collections'>
"! Info:
Concatenate this array with another array, value. Returns a new array, and does not change the two arrays it was created from.
Examples:
|a b c|
a := Array with: 1 with: 2.
b := Array with: 3 with: 4 with: 5.
c := a + b.
\"prints '12345'\"
c do: [ :n | n print. ].
"
+ value [
| size1 size2 ret |
size1 := self size.
size2 := value size.
ret := self class new: (size1 + size2).
ret replaceFrom: 1 to: size1 with: self.
ret replaceFrom: size1+1 to: size1+size2 with: value.
^ ret
]

"! Info:
Check if this array is smaller than an another array, arg. Compares the arrays one element at a time, and returns true on first instance of a smaller element.

Examples:
"
< anArray [
| size1 size2 |
size1 := self size. 
size2 := anArray size.
1 to: (size1 min: size2) do: [ :i | 
	(self at: i) ~= (anArray at: i) ifTrue: [ 
		^ (self at: i) < (anArray at: i) 
	]
].
^ size1 < size2
]

"! Info:
Check if this array is equal to another array, anArray 

Examples:
"
= anArray [
(anArray isKindOf: Array) ifFalse: [
	^ super = anArray.
].
self size = anArray size ifFalse: [ 
	^ false 
].
1 to: self size do: [ :i | 
	(self at: i) = (anArray at: i) ifFalse: [ 
		^ false 
	]
].
^ true
]

"! Info:
Return the value at position index in the array (indexes start at 1)
Examples:
\"prints '8'\"
(#(1 2 3 5 8 13 21) at: 5) printNl.
"
at: index [
<arrayAt self index>
(self includesKey: index) ifFalse: [ 
	self badIndex 
].
self primitiveFailed
]

"! Info:
Return the value at posiition index in the array, execute errorBlock on error (out of bounds).

Examples:
"
at: index ifAbsent: errorBlock [
<arrayAt self index>
errorBlock value
]

"! Info:
Insert a value into the array at index 

Examples:
"
at: index put: value [
<arrayAtPut value self index>
(self includesKey: index) ifFalse: [ 
	self badIndex 
].
self primitiveFailed
]

"! Info:
Error Handler called on bad array index 

Examples:
"
badIndex [
self error: #sysArrIdx
]

"! Info:
Execute aBlock on each element of the array 

Examples:
"
do: aBlock [
1 to: self size do: [ :i | 
	aBlock value: (self at: i)
]
]

"! Info:
Create a new array with the elements being the values [ low .. high ] 

Examples:
"
from: low to: high [
| start stop size ret |
start := low max: 0.
stop := high min: self size.
size := (stop - start + 1) max: 0.
ret := (self class) new: size.
1 to: size do: [ :i |
	ret at: i put: (self at: start).
	start := start + 1
].
^ ret
]

"! Info:
Return true if this array contains value 

Examples:
"
includes: value [
self do: [ :elt | 
	elt = value ifTrue: [ 
		^ true 
	]
].
^ false
]

"! Info:
Check if this array includes index (eg, if 1 <= index <= size) 

Examples:
"
includesKey: index [
^ index between: 1 and: self size
]

"! Info:
Return the index of value in this array, otherwise return nil 

Examples:
"
indexOf: value [
1 to: self size do: [ :i |
	((self at: i) = value) ifTrue: [ 
		^ i
	]
].
^ nil
]

"! Info:
Create a copy of this array and insert value between the elements at index and (index + 1). The new array will be one element larger.

Examples:
"
insert: value at: index [
| ret newSize |
newSize := self size + 1.
ret := self class new: newSize.
ret replaceFrom: 1 to: index - 1 with: self.
ret at: index put: value.
ret replaceFrom: index + 1 to: newSize with: self startingAt: index.
^ ret
]

"! Info:
Create a copy of this array with the value at index removed. The new array will be one element smaller 

Examples:
"
removeIndex: index [
| ret newSize |
newSize := self size - 1.
ret := self class new: newSize.
ret replaceFrom: 1 to: index - 1 with: self.
ret replaceFrom: index to: newSize with: self startingAt: index + 1.
^ ret
]

"! Info:
Copy elements from replacement (starting at index 1), into this array in the range [ start .. stop ] 

Examples:
"
replaceFrom: start to: stop with: replacement [
^ self replaceFrom: start to: stop with: replacement startingAt: 1
]

"! Info:
Copy elements from replacement (starting at index startAt), into this array in the range [ start .. stop ] 

Examples:
"
replaceFrom: start to: stop with: replacement startingAt: startAt [
<stringReplace start stop replacement startAt self>.
0 to: (stop - start) do: [ :i |
	self at: (i + start) put: (replacement at: (i + startAt))
]
]

"! Info:
Return the number of elements in this array 

Examples:
"
size [
<objectSize self>
]

"! Info:
Create a copy of this array with an additional element, elt 

Examples:
"
with: elt [
| ret size |
size := self size.
ret := self class new: size + 1.
ret replaceFrom: 1 to: size with: self.
ret at: size + 1 put: elt.
^ ret
]

]

"! Class methods for Array "
MetaCollection subclass: MetaArray [
<category: 'Library-Collections'>
"! Info:
Create a new Array with 0 elements 

Examples:
"
new [
^ self new: 0
]

"! Info:
Create a new array and specify its size.
Examples:
\"Create a new array with 10 elements\"
|a|
a := Array new: 10.
\"prints '10'\"
a size printNl.
"
new: sz [
<objectNew self sz>
]

"! Info:
Create a new Array with 1 element
Examples:
|a|
a := Array with: 42.
\"prints '42'\"
(a at: 1) printNl.
"
with: a [
| ret |
ret := self new: 1.
ret at: 1 put: a.
^ ret
]

"! Info:
Create a new Array with 2 elements
Examples:
|a|
a := Array with: 'foo' with: 'bar'.
"
with: a with: b [
| ret |
ret := self new: 2.
ret at: 1 put: a.
ret at: 2 put: b.
^ ret
]

"! Info:
Create a new Array with 3 elements
Examples:
|a|
a := Array with: 'Hello '
           with: 'from '
           with: 'Foxtalk'.
\"prints 'Hello from Foxtalk'\"
a do: [ :word |
	word print.
].
"
with: a with: b with: c [
| ret |
ret := self new: 3.
ret at: 1 put: a.
ret at: 2 put: b.
ret at: 3 put: c.
^ ret
]

]

